package com.srwl.mytx.im.handler;

import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.srwl.mytx.Constant;
import com.srwl.mytx.domain.Message;
import com.srwl.mytx.im.MessageBuilder;
import com.srwl.mytx.im.core.MessageReceivedQueue;
import com.srwl.mytx.im.core.NettyTcpClient;
import com.srwl.mytx.im.protobuf.MessageProtobuf;

import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * <p>@ProjectName:     NettyChat</p>
 * <p>@ClassName:       LoginAuthRespHandler.java</p>
 * <p>@PackageName:     com.freddy.im</p>
 * <b>
 * <p>@Description:     握手认证消息响应处理handler</p>
 * </b>
 * <p>@author:          FreddyChen</p>
 * <p>@date:            2019/04/07 23:11</p>
 * <p>@email:           chenshichao@outlook.com</p>
 */
public class LoginAuthRespHandler extends ChannelInboundHandlerAdapter {
    private static final String TAG = "LoginAuthRespHandler";
    private NettyTcpClient imsClient;

    public LoginAuthRespHandler(NettyTcpClient imsClient) {
        this.imsClient = imsClient;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        MessageProtobuf.Msg loginRespMsg = (MessageProtobuf.Msg) msg;
        if (loginRespMsg == null || loginRespMsg.getHead() == null) {
            return;
        }

        if (Constant.IM_TYPE_LOGIN == loginRespMsg.getHead().getMsgType()) {
            int status = -1;
            String reason = "";
            JSONObject jsonObj = null;
            try {
                jsonObj = JSON.parseObject(loginRespMsg.getBody());
                status = jsonObj.getIntValue("status");
                if (jsonObj.containsKey("reason")) {
                    reason = jsonObj.getString("reason");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (status == 1) {
                    Log.i(TAG, "channelRead: 登录完成" + jsonObj.toJSONString());
                    long loginTimeStamp = loginRespMsg.getHead().getTimestamp();
                    imsClient.setLoginTimeStamp(loginTimeStamp);
                    imsClient.onLoginSuccess();
                    // 握手成功，马上先发送一条心跳消息，至于心跳机制管理，交由HeartbeatHandler
                    MessageProtobuf.Msg heartbeatMsg = imsClient.getHeartbeatMsg();
                    if (heartbeatMsg == null) {
                        return;
                    }

                    // 握手成功，检查消息发送超时管理器里是否有发送超时的消息，如果有，则全部重发
                    imsClient.getMsgTimeoutTimerManager().onResetConnected();

                    Log.d(TAG, "channelRead: 发送心跳消息：" + heartbeatMsg + "当前心跳间隔为：" + imsClient.getHeartbeatInterval() + "ms\n");
                    imsClient.sendMsg(heartbeatMsg);

                    // 添加心跳消息管理handler
                    imsClient.addHeartbeatHandler();

                    if (jsonObj.containsKey("offLineMessage")) {
                        List<Message> offLineMessage = jsonObj.getJSONArray("offLineMessage").toJavaList(Message.class);
                        handleOffLineMessage(loginRespMsg.getHead().getFromId(), offLineMessage);
                    }
                } else {

                    //imsClient.getMsgDispatcher().onLoginFail(loginRespMsg);
                     imsClient.resetConnect();//
                }
            }
        } else {
            // 消息透传
            ctx.fireChannelRead(msg);
        }
    }

    private void handleOffLineMessage(String fromId, List<Message> offLineMessage) {
        //目前离线消息是一次性拉回全部，并没有分页拉取什么的，所以收到离线消息后，需告诉服务端，已经收到，可以清除离线消息了
        MessageProtobuf.Msg offLineReceivedReportMsg = MessageBuilder.buildOffLineReceivedReportMsg(fromId);
        imsClient.sendMsg(offLineReceivedReportMsg);

        for (int i = 0; i < offLineMessage.size(); i++) {
            Message message = offLineMessage.get(i);
            String messageId = message.getId();
            if (MessageReceivedQueue.getInstance().isRepeatMessage(messageId)) {
                offLineMessage.remove(i);
                i--;
            }
            //不管是否重复了，都重新加入接收队列，这样可以刷新加入时间
            MessageReceivedQueue.getInstance().addInQueue(messageId);

        }
        Log.d(TAG, "channelRead: 重连收到离线消息数量： " + offLineMessage.size());
        Collections.sort(offLineMessage, new Comparator<Message>() {
            @Override
            public int compare(Message o1, Message o2) {

                Date created = o1.getCreated();
                Date created1 = o2.getCreated();
                if (created == null || created1 == null) {
                    return 0;
                }
                if (created.before(created1)) {
                    return -1;
                } else {
                    return 1;
                }

            }
        });

        imsClient.getMsgDispatcher().receivedOffLineMsg(offLineMessage);

//                        JSONArray offLineMessageObject = jsonObj.getJSONArray("offLineMessage");
//                        Log.d(TAG, "channelRead: 离线消息数量 " + offLineMessageObject.size());
//                        for (Object o : offLineMessageObject) {
//                            byte[] bytes = o.toString().getBytes();
//                            MessageProtobuf.Msg offLineMessage = MessageProtobuf.Msg.newBuilder().mergeFrom(bytes).build();
//                            imsClient.getMsgDispatcher().receivedMsg(offLineMessage);
//                        }
    }
}
